/******************************************************************************
 *                  Shanghai ChipON Micro-Electronic Co.,Ltd
 ******************************************************************************
 *  @File Name        : kf8a100fxx_i2c.h
 *  @Author           : ChipON AE/FAE Group
 *  @Date             : 2023-12-19
 *  @HW Version       : KF8A100Fxx
 *  @Lib Version      : V2.0.1
 *  @Description      : This file provides the driver for the i2c module
 ******************************************************************************
 *  Copyright (C) by Shanghai ChipON Micro-Electronic Co.,Ltd
 *  All rights reserved.
 *
 *  This software is copyright protected and proprietary to
 *  Shanghai ChipON Micro-Electronic Co.,Ltd.
 *****************************************************************************/
/******************************************************************************
 *  |Date        |Version  |Author       |Description
 ******************************************************************************
 *  |2023-12-27  |V2.0     |Wang Junxiong|New creat
 *****************************************************************************/

#ifndef KF8A100FXX_I2C_H
#define KF8A100FXX_I2C_H

#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************
 *                      Include Files
 *****************************************************************************/
#include "kf8a100fxx.h"
/******************************************************************************
 *                      Macro or Inline
 *****************************************************************************/

/**
 * @brief timeout: time limit for flag query, Must not be less than SystemClock/4/BaudRate*9/8
 * You can set it larger if time permits, SystemClock/4/BaudRate*9/8*1.5
 * 0 ~ 65535
 *
 */
#define I2C_TIMEOUT_CONFIG (uint16_t)67u

/* 1 = Indicates that the last received or sent byte is data
 * 0 = Indicates that the last byte received or sent is an address */
#define I2C_DATA_BIT SSCIDA
/* 0 = No stop bit was detected last time
 * 1 = Indicates that the stop bit was detected last time */
#define I2C_STOP_BIT SSCISTOP
/* 0 = Indicates that no start bit was detected last time
 * 1 = Indicates that the start bit was detected last time */
#define I2C_START_BIT SSCISTART
/* 0 = Write
 * 1 = Read  */
#define I2C_RW_BIT SSCIRW
/* 0 = Address update is not required
 * 1 = Indicates that the user needs to update the address in the SSCIxADD register  */
#define I2C_UPDATE_BIT SSCIUA
/* 0 = Reception not completed, SSCIxBUFR empty (Receive mode)
 * 0 = Send complete, SSCIxBUFR empty (Transmit mode)
 * 1 = Receive completed, SSCIBUFR full (Receive mode)
 * 1 = Sending, SSCIBUFR full (Transmit mode) */
#define I2C_BUF_FULL_BIT SSCIBUF
/* I2C data receive buffer/transmit register */
#define I2C_BUFFER SSCIBUFR
/* I2C SCK release control bit*/
#define I2C_SCK_CTRL_BIT SSCICKP
/* I2C Receive overflow indicating bit*/
#define I2C_OVERFLOW_BIT SSCIOV

/**
 * @brief i2c module disable/enable
 * 0: disable, 1:enable
 *
 */
#define I2C_ENABLE(x) (SSCIEN = (x))
/*****************************************************************************
 *                      Typedef Definitions
 *****************************************************************************/
/**
 * @brief i2c mode
 */
typedef enum
{
    I2C_SLAVE_7BIT_MODE  = 6u,
    I2C_SLAVE_10BIT_MODE = 7u,
    /** @brief clock = FOSC/(4*(SSCIADD+1))  */
    I2C_MASTER_MODE = 8u,
    /** @brief slave idle mode  */
    I2C_FIRMWARE_CONTROL_MASTER_MODE = 11u,
    I2C_SLAVE_7BIT_INTERRUPT_MODE    = 14u,
    I2C_SLAVE_10BIT_INTERRUPT_MODE   = 15u
} I2c_ModeType;

/**
 * @brief I2c answer type
 */
typedef enum
{
    I2C_ANSWER    = 0u,
    I2C_NO_ANSWER = 1u,
} I2c_AnsType;

/**
 * @brief I2c data or address type
 */
typedef enum
{
    I2C_ADDR = 0u,
    I2C_DATA = 1u,
} I2c_DatType;

/**
 * @brief I2c stop bit type
 */
typedef enum
{
    I2C_NO_STOP = 0u,
    I2C_STOP    = 1u,
} I2c_StpType;

/**
 * @brief I2c start bit type
 */
typedef enum
{
    I2C_NO_START = 0u,
    I2C_START    = 1u,
} I2c_StaType;

/**
 * @brief I2c read/write information bit type
 */
typedef enum
{
    I2C_WRITE = 0u,
    I2C_READ  = 1u,
} I2c_RwType;

/**
 * @brief I2c update address bit type
 */
typedef enum
{
    I2C_NO_UPDATE = 0u,
    I2C_UPDATE    = 1u,
} I2c_UpdType;

/**
 * @brief I2c update address bit type
 */
typedef enum
{
    I2C_EMPTY = 0u,
    I2C_FULL  = 1u,
} I2c_BufType;

/**
 * @brief I2c SCK release control bit type
 */
typedef enum
{
    I2C_SCK_DISABLE = 0u,
    I2C_SCK_ENABLE  = 1u,
} I2c_SckType;

/**
 * @brief I2C Receive overflow indicating bit type
 */
typedef enum
{
    I2C_NO_OVERFLOW = 0u,
    I2C_OVERFLOW    = 1u,
} I2c_OvType;

/**
 * @brief I2C timeout error type.
 */
typedef enum
{
    I2C_OK,
    I2C_START_TIMEOUT,
    I2C_STOP_TIMEOUT,
    I2C_ACK_TIMEOUT,
    I2C_WRITE_TIMEOUT,
    I2C_READ_TIMEOUT
} I2c_StatusType;

/**
 * @brief Address of the slave or baud rate of the host
 * Address: high 7 bits are valid
 *
 * baud rate: Lower 7 bits are valid
 * When the system clock frequency is 16MHz:
 * 100 kHz - 39 (theoretical error: 0.00%)
 * 150 kHz - 26 (theoretical error: 1.23%)
 * 400 kHz -  9 (theoretical error: 0.00%)
 *
 */
typedef uint8_t I2c_Addr_BaudRate;
/******************************************************************************
 *                      Export Variables
 *****************************************************************************/

/******************************************************************************
 *                      Export Functions
 *****************************************************************************/

/**
 * @brief I2C Initialization
 *
 * @param Mode I2C mode
 * @param AddrOrBaudRate The I2C slave mode is an address register with the high 7 bits active, and the I2C master mode
 * is a baud rate register with the low 7 bits active.
 * When the system clock frequency is 16MHz:
 * 100 kHz - 39 (theoretical error: 0.00%)
 * 150 kHz - 26 (theoretical error: 1.23%)
 * 400 kHz -  9 (theoretical error: 0.00%)
 */
void I2c_Init(I2c_ModeType Mode, I2c_Addr_BaudRate AddrOrBaudRate);

/**
 * @brief I2C DeInitialization
 *
 */
void I2c_DeInit(void);

/**
 * @brief Enable or disable I2C/SPI/SSCIEN
 *
 * @param State 0: disable, 1: enable
 */
void I2c_Enable(uint8_t State);

/**
 * @brief I2c host initiates start signal
 *
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 1: I2C_START_TIMEOUT,
 */
I2c_StatusType I2c_Start(void);

/**
 * @brief I2c host initiates stop signal
 *
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 2: I2C_STOP_TIMEOUT,
 */
I2c_StatusType I2c_Stop(void);

/**
 * @brief I2c host sends one byte of data
 *
 * @param c Single-byte data to be sent
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 4: I2C_WRITE_TIMEOUT,
 */
I2c_StatusType I2c_SendB(uint8_t c);

/**
 * @brief I2c host receives one byte of data
 *
 * @return uint8_t One byte of data received
 */
uint8_t I2c_RcvB(void);

/**
 * @brief The I2c host sends an answer signal
 *
 * @param a 0 is an answer, 1 is no answer
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 3: I2C_ACK_TIMEOUT,
 */
I2c_StatusType I2c_Ack(I2c_AnsType a);

/**
 * @brief The I2c host sends multiple bytes in succession
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param Buf data address
 * @param Cnt data length
 * @param Addr i2c slave address
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 1: I2C_START_TIMEOUT,
 * 2: I2C_STOP_TIMEOUT,
 * 3: I2C_ACK_TIMEOUT,
 * 4: I2C_WRITE_TIMEOUT,
 * 5: I2C_READ_TIMEOUT
 */
I2c_StatusType I2c_SendDataWrite(const uint8_t *Buf, uint8_t Cnt, uint8_t Addr);

/**
 * @brief I2c host reads multiple bytes consecutively
 *
 * @attention This function cannot be called within an interrupt service routine.
 *
 * @param Buf data address
 * @param Cnt data length
 * @param Addr i2c slave address
 * @return I2c_StatusType
 * 0: I2C_OK,
 * 1: I2C_START_TIMEOUT,
 * 2: I2C_STOP_TIMEOUT,
 * 3: I2C_ACK_TIMEOUT,
 * 4: I2C_WRITE_TIMEOUT,
 * 5: I2C_READ_TIMEOUT
 */
I2c_StatusType I2c_SendDataRead(uint8_t *Buf, uint8_t Cnt, uint8_t Addr);

#ifdef __cplusplus
}
#endif

#endif
/* EOF */
